//Projeto para LPC1111/202	=	8k Flash 4k RAM

#include "includes.h"
#include "i2C.h"
#include "teclado.h"

#define DLY_100US             550
#define ACK					  0x06

#define	TMP_PULSO_BAIXO		3	//x 10ms
#define	TMP_PULSO_ALTO		5	//x 10ms


#include <yfuns.h>

volatile unsigned int 	Timer10ms[NUMTMR10MS];

unsigned char Est_Rx;
unsigned int Est_BotProc;
unsigned int Est_BotAgua;
unsigned int Est_inicial;
unsigned int Est_configuracao;
unsigned char tamanho;
char Buff_Rx[32];
char Buff_Tx[32];

unsigned char Est_Contador[5];
unsigned char BCC_TX;
unsigned char BCC_RX;

/*variable for clitical section entry control*/
Int32U CriticalSecCntr;
volatile Int32U Ticks;
/** external data **/

//** internal functions **/
static int MyLowLevelGetchar(void);
void NVIC_IntEnable(Int32U IntNumber);
void NVIC_IntDisable(Int32U IntNumber);
void NVIC_ClrPend(Int32U IntNumber);
void NVIC_IntPri(Int32U IntNumber, Int8U Priority);
void InitClock(Int32U clock, Int32U ahbdiv);
Int32U SYS_GetMainClk(void);
void UART_Init (Int32U BaudRate);
size_t __write(int Handle, const unsigned char * Buf, size_t Bufsize);
size_t __read(int handle, unsigned char * buffer, size_t size);
void DelayResolution100us(Int32U Dly);
void GpioInit(void);
void Zera_Timers(void);
//void CtrlTimers(void);
void CT32B0_IRQHandler (void);
void CT32B0_Init(Int32U tps);
void CT32B0_Stop(void);

void UART_PutString(char *Buf, int Size);

/** public functions **/
/*************************************************************************
 * Function Name: NVIC_IntEnable
 * Parameters: IntNumber - Interrup number
 * Return: void
 *
 * Description: Enable interrup at NVIC
 *
 *
 *************************************************************************/
void NVIC_IntEnable(Int32U IntNumber)
{
	volatile unsigned long * pNVIC_SetEn = &SETENA0;
	
	assert((NVIC_WAKE_UP0 <= IntNumber) && (NVIC_PIO_0 >= IntNumber));
	IntNumber -= NVIC_WAKE_UP0;
	
	pNVIC_SetEn += IntNumber/32;
	*pNVIC_SetEn = (1UL<<(IntNumber%32));
	
}

/*************************************************************************
 * Function Name: NVIC_IntDisable
 * Parameters: IntNumber - Interrup number
 * Return: void
 *
 * Description: Disables interrup at NVIC
 *
 *
 *************************************************************************/
void NVIC_IntDisable(Int32U IntNumber)
{
	volatile unsigned long * pNVIC_ClrEn = &CLRENA0;
	
	assert((NVIC_WAKE_UP0 <= IntNumber) && (NVIC_PIO_0 >= IntNumber));
	IntNumber -= NVIC_WAKE_UP0;
	
	pNVIC_ClrEn += IntNumber/32;
	*pNVIC_ClrEn = (1UL<<(IntNumber%32));
	
}

/*************************************************************************
 * Function Name: NVIC_ClrPend
 * Parameters: IntNumber - Interrup number
 * Return: void
 *
 * Description:Clear pending interrupt at NVIC
 *
 *
 *************************************************************************/
void NVIC_ClrPend(Int32U IntNumber)
{
	volatile unsigned long * pNVIC_ClrPend = &CLRPEND0;
	
	assert((NVIC_WAKE_UP0 <= IntNumber) && (NVIC_PIO_0 >= IntNumber));
	IntNumber -= NVIC_WAKE_UP0;
	
	pNVIC_ClrPend += IntNumber/32;
	*pNVIC_ClrPend = (1UL<<(IntNumber%32));
	
}

/*************************************************************************
 * Function Name: NVIC_ClrPend
 * Parameters: IntNumber - Interrup number, Interrupt Priority
 * Return: void
 *
 * Description:Sets Interrupt priority
 *
 *
 *************************************************************************/
void NVIC_IntPri(Int32U IntNumber, Int8U Priority)
{
	volatile Int8U * pNVIC_IntPri = (Int8U *)&IP0;
	
	assert((NVIC_WAKE_UP0 <= IntNumber) && (NVIC_PIO_0 >= IntNumber));
	IntNumber -= NVIC_WAKE_UP0;
	pNVIC_IntPri += IntNumber;
	*pNVIC_IntPri = Priority;
}

/*******  ******************************************************************
 * Function Name: InitClock
 * Parameters: clock, AHB devider
 * Return: void
 *
 * Description: Initialize PLL to desired clock and  AHB devider
 *              Sys clock is Sys PLL output
 *
 *
 *************************************************************************/
void InitClock(Int32U clock, Int32U ahbdiv)
{
	/*Sys Oscilator Enable*/
	SYSOSCCLTRL = (MAIN_OSC_FREQ>(20MHZ))?(0x2):(0x0);
	/*Power Up SYS Oscilator*/
	PDRUNCFG_bit.SYSOSC_PD = 0;
	/*Enable Internal RC oscilator*/
	PDRUNCFG_bit.IRC_PD = 0;
	/*Select internal RC oscilator for
	Sys clock source*/
	MAINCLKUEN = 0;
	MAINCLKSEL = 0;
	MAINCLKUEN = 1;
	/*Configure SYS PLL*/
	/*Power Down SYS PLL*/
	PDRUNCFG_bit.SYSPLL_PD = 1;
	/*Select Sys Oscilator for
	SYS PLL source*/
	SYSPLLCLKUEN = 0;
	SYSPLLCLKSEL = 0;//para usar RC interno 1 para usar crystal externo;
	SYSPLLCLKUEN = 1;
	/*Calc M*/
	Int32U m = clock/MAIN_OSC_FREQ - 1;
	
	assert(m<32);
	/*Configure PLL frequency*/
	SYSPLLCTRL =  (m)    /*MSEL*/
				|  (0<<5) /*PSEL = 1*/
				|  (0<<7) /*DIRECT = 0*/
				|  (0<<8); /*BYPASS=0*/

	/*Power Up PLL*/
	PDRUNCFG_bit.SYSPLL_PD = 0;
	/*Set Sys AHB Clock devider*/
	SYSAHBCLKDIV_bit.DIV = ahbdiv;
	/*Wain until PLL locks*/
	while(!(SYSPLLSTAT_bit.LOCK));
	/*Select Sys PLL Output for
	Sys clock source*/
	//  MAINCLKUEN = 0;
	//  MAINCLKSEL = 3;
	//  MAINCLKUEN = 1;
}

/*************************************************************************
 * Function Name: SYS_GetMainClk
 * Parameters: none
 * Return: Int32U
 *
 * Description: return Main Clock [Hz]
 *
 *************************************************************************/
Int32U SYS_GetMainClk(void)
{
	Int32U Clk;
	switch(MAINCLKSEL_bit.SEL)
	{
		case 0:
			Clk = I_RC_OSC_FREQ;
			break;
		case 1:
			Clk = MAIN_OSC_FREQ;
			break;
		case 2:
			Clk = WDT_OSC_FREQ;
			break;
		case 3:
			switch(SYSPLLCLKSEL_bit.SEL)
			{
				case 0:
					Clk = I_RC_OSC_FREQ;
					break;
				case 1:
					Clk = MAIN_OSC_FREQ;
					break;
				case 2:
					Clk = WDT_OSC_FREQ;
					break;
				
				default:
					Clk = 0;
					break;
			}
			
			Clk *= (SYSPLLCTRL_bit.MSEL+1);
			break;
		
		default:
			Clk = 0;
			break;
	}
	return Clk;
}

void UART_Init (Int32U BaudRate)
{
	Int32U Pclk;
	/*Enable Clocks*/
	UARTCLKDIV = 1;
	/**/
	while((Pclk=SYS_GetMainClk()/UARTCLKDIV)> 70MHZ)
	{
		UARTCLKDIV ++;
	}
	/*Enable UART register clock*/
	SYSAHBCLKCTRL_bit.UART = 1;
	/*Enable I/O Configuration registers*/
	SYSAHBCLKCTRL_bit.IOCON = 1;
	
	IOCON_PIO1_6 = 1;         //Uart RX function select
	IOCON_PIO1_7 = 1;         //Uart RX function select
	
	U0LCR_bit.WLS = 3;        //Serlect 8-Bits
	U0LCR_bit.SBS = 0;        //One Stop Bit
	U0LCR_bit.PE = 0;         //No parity
	
	U0LCR_bit.DLAB = 1;       //Devisor Latch Access ebabled
	//Set UART0 BAUDRATE
	U0DLL = ((((Pclk+8)/16)+BaudRate/2)/BaudRate)%256;  //
	U0DLM = ((((Pclk+8)/16)+BaudRate/2)/BaudRate)/256;  //
	U0LCR_bit.DLAB = 0;           //Clear Devisor Latch Access bit
	
	U0FCR = (1<<0);     //Enable UART0 FIFOs.
	U0TER = (1<<7);     //Enable Transmission
}
/*************************************************************************
 * Function Name: __write
 * Parameters: Low Level cahracter output
 *
 * Return:
 *
 * Description:
 *
 *************************************************************************/
size_t __write(int Handle, const unsigned char * Buf, size_t Bufsize)
{
	size_t nChars = 0;
	
	for (/*Empty */; Bufsize > 0; --Bufsize)
	{
		while( !U0LSR_bit.THRE );  //Wait
		U0THR = * Buf++;
		++nChars;
	}
	return nChars;
}

void UART_PutString(char *Buf, int Size)
{
	int nChars = 0;
	LED_ON(TX_PIN);
	for (/*Empty */; Size > 0; --Size)
	{
		while( !U0LSR_bit.THRE );  //Wait
		U0THR = * Buf++;
		++nChars;
	}

        DelayResolution100us(1);
        LED_OFF(TX_PIN);
	//return nChars;
}


/*************************************************************************
 * Function Name: __read
 * Parameters: Low Level cahracter input
 *
 * Return:
 *
 * Description:
 *
 *************************************************************************/
size_t __read(int handle, unsigned char * buffer, size_t size)
{
	int nChars = 0;
	
	/* This template only reads from "standard in", for all other file
	* handles it returns failure. */
	if (handle != _LLIO_STDIN)
	{
		return _LLIO_ERROR;
	}
	
	for (/* Empty */; size > 0; --size)
	{
		int c = MyLowLevelGetchar();
		if (c < 0)
			break;
		
		*buffer++ = c;
		++nChars;
	}
	return nChars;
}

/*************************************************************************
 * Function Name: DelayResolution100us
 * Parameters: Int32U Dly
 * Return: void
 *
 * Description: Delay Dly * [100us]
 *		
 *************************************************************************/
void DelayResolution100us(Int32U Dly)
{
	for(; Dly; Dly--)
	{
		for(volatile Int32U j = DLY_100US; j; j--)
		{
		}
	}
}

/*************************************************************************
 * Function Name: GpioInit
 * Parameters: void
 * Return: void
 *
 * Description: Reset all GPIO pins to default: primary function
 *
 *************************************************************************/
void GpioInit(void)
{
	// Set to inputs
	GPIO0DIR = 0x00000FCC;
	GPIO1DIR = 0x000007B8|(1<<5);
	GPIO2DIR = 0x00000000;
	GPIO3DIR = 0x00000034;
	
	// Reset all GPIO pins to default primary function
	IOCON_PIO2_6 = 0x50;
	IOCON_PIO2_0 = 0xD0;
	IOCON_RESET_PIO0_0 = 0x50;
	IOCON_PIO0_1 = 0x50;
	IOCON_PIO1_8 = 0xC8;
	IOCON_PIO0_2 = 0x50;
	IOCON_PIO2_7 = 0x50;
	IOCON_PIO2_8 = 0x50;
	IOCON_PIO2_1 = 0x50;
	IOCON_PIO0_3 = 0x50;
	IOCON_PIO1_9 = 0xC0;
	IOCON_PIO2_4 = 0x50;
	IOCON_PIO2_5 = 0x50;

	//  IOCON_PIO0_6 = 0x50;
	IOCON_PIO0_6 = 0xC8;		//alterado AM para colocar pull-down
	//  IOCON_PIO0_7 = 0x50;
	IOCON_PIO0_7 = 0x50;//0xC8;		//alterado AM para colocar pull-down
	//  IOCON_PIO0_8 = 0x50;
	IOCON_PIO0_8 = 0x50;//0xC8;		//alterado AM para colocar pull-down
	IOCON_PIO0_9 = 0x50;//0xC8;		//alterado AM para colocar pull-down

	IOCON_PIO2_9 = 0x50;
	IOCON_PIO2_10 = 0x50;
	IOCON_PIO2_2 = 0x50;
	IOCON_SWCLK_PIO0_10 = 0xC9;	//0x50;
	IOCON_PIO2_11 = 0x50;
	IOCON_PIO3_0 = 0x50;
	IOCON_PIO3_1 = 0x50;
	IOCON_PIO2_3 = 0x50;
	IOCON_PIO3_2 = 0x50;
	IOCON_PIO1_5 = 0x50;
	IOCON_PIO3_3 = 0x50;
	
	IOCON_PIO1_10 = 0xC0;
	IOCON_R_PIO0_11 = 0x81;//D0;
	IOCON_R_PIO1_0 = 0xC1;
	IOCON_R_PIO1_1 = 0xC1;
	IOCON_R_PIO1_2 = 0xC1;
	IOCON_SWDIO_PIO1_3 = 0xC1;
	IOCON_PIO1_4 = 0xD0;
	IOCON_PIO1_11 = 0xD0;
	
	IOCON_PIO0_4 = 0x00;
	IOCON_PIO0_5 = 0x00;
}


void Zera_Timers(void)
{
	// coloca todos os temporizadores no estado inicial	
	unsigned int i;
	for (i = 0; i < NUMTMR10MS; i++)
	{
		Timer10ms[i] = 0x00;
	}	
}

/*************************************************************************
 * Function Name: TMR0_IRQHandler
 * Parameters: none
 *
 * Return: none
 *
 * Description: Timer 0 interrupt handler
 *
 *************************************************************************/
void CT32B0_IRQHandler (void)
{
	unsigned int i;

	++Ticks;

	Timer10ms[0]++;
	for (i = 1; i < NUMTMR10MS; i++)
	{
		if(Timer10ms[i] > 0)
		{
			Timer10ms[i]--;
		}
	}
	// clear interrupt
	TMR32B0IR_bit.MR0INT = 1;
	/**/
	NVIC_ClrPend(NVIC_CT32B0);
}

void CT32B0_Init(Int32U tps)
{
	Ticks = 0;
	// Enable TIM0 clocks
	SYSAHBCLKCTRL_bit.CT32B0 = 1;
	
	// Init Time0
	TMR32B0TCR_bit.CE = 0;     // counting  disable
	TMR32B0TCR_bit.CR = 1;     // set reset
	TMR32B0TCR_bit.CR = 0;     // release reset
	TMR32B0CTCR_bit.CTM = 0;   // Timer Mode: every rising PCLK edge
	TMR32B0MCR_bit.MR0I = 1;   // Enable Interrupt on MR0
	TMR32B0MCR_bit.MR0R = 1;   // Enable reset on MR0
	TMR32B0MCR_bit.MR0S = 0;   // Disable stop on MR0
	// set timer 0 period
	TMR32B0PR = 0;
	TMR32B0MR0 = (SYS_GetMainClk()/(SYSAHBCLKDIV))/(tps);
	// init timer 0 interrupt
	TMR32B0IR_bit.MR0INT = 1;  // clear pending interrupt
	TMR32B0TCR_bit.CE = 1;     // counting Enable
	
	//Zera a RAM dos timers
	Zera_Timers();
	/*Enable NVIC TMR0 Interrupt*/
	NVIC_IntEnable(NVIC_CT32B0);
	NVIC_IntPri(NVIC_CT32B0,16);
}

void CT32B0_Stop(void)
{
	TMR32B0TCR_bit.CE = 0;     // counting  disable
	
	NVIC_IntDisable(NVIC_CT32B0);
	
	SYSAHBCLKCTRL_bit.CT32B0 = 0; // disable clock
}
/*************************************************************************
 * Function Name: main
 * Parameters: none
 *
 * Return: none
 *
 * Description: main
 *
 *************************************************************************/
int main(void)
{
	char BuffDebug[32];
	unsigned int EstRx;
	int cRxSerial;
	unsigned char c;
	unsigned int TeclaValMain, i;
//	static unsigned int Est_Teclas = 0;
	unsigned int ImagemLeds = 0;
	TeclaValMain = 0;
	
	/*Init clock*/
	InitClock(132MHZ, 2);
	/*Enable GPIO Clock*/
	SYSAHBCLKCTRL_bit.GPIO = 1;
	/*Enable IOCON Clock*/
	SYSAHBCLKCTRL_bit.IOCON = 1;
	/*Set all pins as input ports*/
	GpioInit();
	/*Init LED Ports*/
	LED1_DIR |= LED1_MASK;
	LED2_DIR |= LED2_MASK;
	LED3_DIR |= LED3_MASK;
	LED4_DIR |= LED4_MASK;
	LED5_DIR |= LED5_MASK;
	LED6_DIR |= LED6_MASK;
	LED7_DIR |= LED7_MASK;
	LED8_DIR |= LED8_MASK;
	LED9_DIR |= LED9_MASK;
	LED10_DIR |= LED10_MASK;
	LED11_DIR |= LED11_MASK;
	/*Init RELAY Ports*/
	LED_OFF(LED1_PIN);//NAO MUDOU EM NADA
	LED_ON(LED2_PIN);//NAO MUDOU
	LED_OFF(LED3_PIN);//
	LED_OFF(LED4_PIN);
	LED_OFF(LED5_PIN);
	LED_OFF(LED6_PIN);
	LED_OFF(LED7_PIN);
	LED_OFF(LED8_PIN);
	LED_OFF(LED9_PIN);
	LED_OFF(LED10_PIN);
	LED_OFF(LED11_PIN);
        LED_OFF(LED12_PIN);
        LED_OFF(LED13_PIN);
	
	UART_Init(57600);
	/*Enable Timer. Ticks 10 times per second*/
	CT32B0_Init(100);	//o parametro indica ticks por segundo
	
//	DES_HAB_TX(TX_PIN);
	DES_HAB_RX(RX_PIN);

        DES_HAB_LINHA(L2_PIN);
        HAB_LINHA(L3_PIN);
        DES_HAB_LINHA(L1_PIN);

	while(1)
	{
//          	LED_OFF(LED3_PIN);//
//	LED_OFF(LED4_PIN);
//	LED_OFF(LED5_PIN);
//	LED_OFF(LED6_PIN);
//	LED_OFF(LED7_PIN);
//	LED_OFF(LED8_PIN);
//	LED_OFF(LED9_PIN);
//	LED_OFF(LED10_PIN);
//	LED_OFF(LED11_PIN);
//        LED_OFF(LED12_PIN);
//        LED_OFF(LED13_PIN);
//	
//	                 DelayResolution100us(500);
//                         	LED_ON(LED3_PIN);//
//	LED_ON(LED4_PIN);
//	LED_ON(LED5_PIN);
//	LED_ON(LED6_PIN);
//	LED_ON(LED7_PIN);
//	LED_ON(LED8_PIN);
//	LED_ON(LED9_PIN);
//	LED_ON(LED10_PIN);
//	LED_ON(LED11_PIN);
//        LED_ON(LED12_PIN);
//        LED_ON(LED13_PIN);
//	
//                         DelayResolution100us(5000);
        BuffDebug[0]=GPIO1DATA&0x7;
        BuffDebug[1]=((GPIO1DATA>>(11))&1)|((GPIO2DATA&1)<<1);
        UART_PutString(BuffDebug,2);
        DelayResolution100us(500);
          
          
	}
}

/** private functions **/
static int MyLowLevelGetchar(void)
{
	int ch;
	
	if(U0LSR_bit.DR)
	{
		ch = U0RBR;
		if(U0LSR_bit.OE || U0LSR_bit.PE || U0LSR_bit.FE )
		{
			return (ch | 0x10000000);
		}
		return (ch & 0xff);
	}
	return -1;
}

